カスタムIDプロバイダー(Lambda)を使ったAWS Transfer Family (FTP) をCloudFormationで作成する
いわさです。
CloudFormationでAWS Transfer Familyを作成する機会があったのですが、FTPかつLambdaカスタムIDプロバイダーという変わった構成で構築する機会があり、あまりCloudFormationのサンプルがなかったので記事にしてみました。
カスタムIDプロバイダーでLambdaを直接統合する機能は以前紹介しています。
テンプレート
全体像のリポジトリはこちらになります。
VPC一式とTransfer Familyで構成されています。
Transfer FamilyはFTPを使っていて、ドメインはS3です。
カスタムIDプロバイダー用にAPI Gatewayを使わずに直接Lambdaを使っています。 Lambdaから返却するポリシーのベースは前述の記事を参考に作成しましたが、ポリシーの内容はFTPでアクセスするS3バケットの情報やIAMロールを含めています。
この記事ではポイントとなる部分を抜粋して紹介します。
なお、先程のリポジトリにデプロイしたらそのまま動くテンプレートをアップしています。
Transfer::Server
前提として、Transfer FamilyをFTPでアクセスする際は、パブリックインターネットアクセスが出来ません。VPCを使ったプライベートアクセスが前提となっています。
EndpointType
やEndpointDetails
にはVPC関連の情報を設定します。
そして、カスタムIDプロバイダー部分ですが、IdentityProviderType
にAWS_LAMBDA
を、IdentityProviderDetails.Function
にLambda関数のARNを指定します。
細かい制御はLambda関数側で行います。
FTP: Type: AWS::Transfer::Server Properties: Domain: S3 Protocols: - FTP EndpointType: VPC EndpointDetails: SecurityGroupIds: - !Ref SecurityGroup SubnetIds: - !Ref PublicSubnet VpcId: !Ref VPC IdentityProviderType: AWS_LAMBDA IdentityProviderDetails: Function: !GetAtt lambdaFunction.Arn
Lambda
ランタイムはPython3.8を使っています。
冒頭の記事でもLambda関数で返却すべき内容を紹介していますが、ユーザー名とパスワードをここでは固定にしています。
そして、関数の返却値として、IAMロールのARNとホームディレクトリーとなるS3バケットの情報を展開しています。
また、リソースベースポリシーでTransferからのInvokeFunction
を許可することを忘れないようにしましょう。
lambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub ${AWS::StackName}-auth-lambda Role: !GetAtt lambdaExecutionRole.Arn Handler: index.lambda_handler Runtime: python3.8 Code: ZipFile: !Sub - | def lambda_handler(event, context): if event["username"] == "hoge" and event["password"] == "fuga": return { 'Role': '${lambdaReturnRole}', 'Policy': '', 'HomeDirectory': '/${bucketName}/' } else: return {} - { lambdaReturnRole: !GetAtt lambdaReturnRole.Arn, bucketName: !Ref S3Bucket } lambdaFunctionInvokePermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !GetAtt lambdaFunction.Arn Principal: transfer.amazonaws.com SourceArn: !GetAtt FTP.Arn
動作確認
Transfer Familyを構築したら、まずはコンソール上でテストを行ってみると良いです。
カスタムIDプロバイダーの権限忘れなどはここでデバッグすることが出来ます。
カスタムIDプロバイダーは期待どおり動作しました。
しかし、実際にFTPクライアントからの接続も行いましょう。
先程のテストコンソールでは実際のインフラ上で接続を行うわけではないので、セキュリティグループの設定ミスなどは発見出来ません。
ここでは、スタックで作成されたVPC上にEC2インスタンスを構築し、FTPクライアントで接続してファイルアップロードをしてみます。
[ec2-user@ip-10-0-0-241 ~]$ sudo yum -y install ftp 読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00:00 依存性の解決をしています --> トランザクションの確認を実行しています。 ---> パッケージ ftp.x86_64 0:0.17-67.amzn2.0.2 を インストール --> 依存性解決を終了しました。 依存性を解決しました ========================================================================================================================================================================================== Package アーキテクチャー バージョン リポジトリー 容量 ========================================================================================================================================================================================== インストール中: ftp x86_64 0.17-67.amzn2.0.2 amzn2-core 61 k トランザクションの要約 ========================================================================================================================================================================================== インストール 1 パッケージ 総ダウンロード容量: 61 k インストール容量: 96 k Downloading packages: ftp-0.17-67.amzn2.0.2.x86_64.rpm | 61 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction インストール中 : ftp-0.17-67.amzn2.0.2.x86_64 1/1 検証中 : ftp-0.17-67.amzn2.0.2.x86_64 1/1 インストール: ftp.x86_64 0:0.17-67.amzn2.0.2 完了しました!
FTPクライアントをインストールしたので、実際に接続してみましょう。
FTPのエンドポイントと、先程デプロイされたLambda関数内でハードコーディングされているユーザー名とパスワードを使用します。
[ec2-user@ip-10-0-0-241 ~]$ ftp vpce-019625ad18283af2c-xe213jcp.vpce-svc-0cee93c75e789f90b.ap-northeast-1.vpce.amazonaws.com Connected to vpce-019625ad18283af2c-xe213jcp.vpce-svc-0cee93c75e789f90b.ap-northeast-1.vpce.amazonaws.com (10.0.0.173). 220 Service ready for new user. Name (vpce-019625ad18283af2c-xe213jcp.vpce-svc-0cee93c75e789f90b.ap-northeast-1.vpce.amazonaws.com:ec2-user): hoge 331 User name okay, need password for hoge. Password: 230 User logged in, proceed. Remote system type is UNIX. ftp> bi 200 Command TYPE okay. ftp> put hoge.txt local: hoge.txt remote: hoge.txt 227 Entering Passive Mode (10,0,0,173,32,3) 150 File status okay; about to open data connection. 226 Transfer complete.
S3コンソール上でも確認してみます。
期待どおりアップロードされていました。
さいごに
本日はCloudFormationを使って、FTP+LambdaカスタムIDプロバイダーなTransfer Familyを構築してみました。
SFTPやAPI Gateway、Service Managedな構成がウェブ上では非常に多く、ちょっとトライ&エラーで苦労しました。次回以降はこのテンプレートを活用して、FTPクライアント側の検証なども紹介したいと思います。